package com.ruoyi.business.listener;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.wecom.client.WeComUtils;
import com.ruoyi.common.wecom.constants.WeComUrlConstants;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.workflow.domain.WfCopy;
import com.ruoyi.workflow.domain.vo.WfCopyVo;
import com.ruoyi.workflow.mapper.WfCopyMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.common.engine.api.delegate.event.FlowableEventType;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.ruoyi.flowable.common.constant.TaskConstants.PROCESS_INITIATOR;

/**
 * Flowable 全局监听器
 * 流程结束时
 *
 * @author zyb
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ProcessCompleteListener implements FlowableEventListener {

    private final TaskService taskService;
    private final WeComUtils weComUtils;
    private final ISysUserService userService;
    private final WfCopyMapper copyMapper;
    @Resource
    protected HistoryService historyService;

    @Override
    public Collection<? extends FlowableEventType> getTypes() {
        return null;
    }

    @Override
    public void onEvent(FlowableEvent flowableEvent) {

        ExecutionEntityImpl taskEntity = (ExecutionEntityImpl) ((FlowableEntityEvent) flowableEvent).getEntity();
        // 流程实例
        HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery()
            .processInstanceId(taskEntity.getProcessInstanceId()).includeProcessVariables().singleResult();
        Map<String, Object> proInstVariables = historicProcIns.getProcessVariables();
        // 给发起人 发消息
        SysUser fqrUser = userService.selectUserById(Long.parseLong((String) proInstVariables.get(PROCESS_INITIATOR)));
        weComUtils.sendTextMessage(fqrUser.getUserName(),
            WeComUrlConstants.TITLE_2,
            historicProcIns.getProcessDefinitionName() + ";项目：" + proInstVariables.getOrDefault("projectName", ""),
            fqrUser.getNickName());
        // 给抄送人们 发消息
        List<Long> copyUserIds = copyMapper.selectVoList(new LambdaQueryWrapper<WfCopy>()
            .apply("distinct user_id")
            .eq(WfCopy::getInstanceId, historicProcIns.getId())
            .groupBy(WfCopy::getUserId)).stream().map(WfCopyVo::getUserId).filter(Objects::nonNull).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(copyUserIds)) {
            copyUserIds.forEach(v->{
                weComUtils.sendTextMessage(userService.selectUserById(v).getUserName(),
                    WeComUrlConstants.TITLE_5,
                    historicProcIns.getProcessDefinitionName() + ";项目：" + proInstVariables.getOrDefault("projectName", ""),
                    fqrUser.getNickName());
            });
        }

    }

    @Override
    public boolean isFailOnException() {
        return false;
    }

    @Override
    public boolean isFireOnTransactionLifecycleEvent() {
        return false;
    }

    @Override
    public String getOnTransaction() {
        return null;
    }
}
